[Android] For-Loop Performance Oddity

Posted by Jack Holt on Stack Overflow See other posts from Stack Overflow or by Jack Holt
Published on 2010-04-25T04:21:40Z Indexed on 2010/04/25 4:33 UTC
Read the original article Hit count: 407

Filed under:
|

I just noticed something concerning for-loop performance that seems to fly in the face of the recommendations given by the Google Android team. Look at the following code:

package com.jackcholt;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class Main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        loopTest();
        finish();
    }

    private void loopTest() {
        final long loopCount = 1228800;
        final int[] image = new int[8 * 320 * 480];
        long start = System.currentTimeMillis();
        for (int i = 0; i < (8 * 320 * 480); i++) {
            image[i] = i;
        }
        for (int i = 0; i < (8 * 320 * 480); i++) {
            image[i] = i;
        }

        Log.i("loopTest", "Elapsed time (recompute loop limit): " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        for (int i = 0; i < 1228800; i++) {
            image[i] = i;
        }
        for (int i = 0; i < 1228800; i++) {
            image[i] = i;
        }
        Log.i("loopTest", "Elapsed time (literal loop limit): " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        for (int i = 0; i < loopCount; i++) {
            image[i] = i;
        }
        for (int i = 0; i < loopCount; i++) {
            image[i] = i;
        }
        Log.i("loopTest", "Elapsed time (precompute loop limit): " + (System.currentTimeMillis() - start));
    }
}

When I run this code I get the following output in logcat:

I/loopTest(  726): Elapsed time (recompute loop limit): 759
I/loopTest(  726): Elapsed time (literal loop limit): 755
I/loopTest(  726): Elapsed time (precompute loop limit): 1317

As you can see the code that seems to recompute the loop limit value on every iteration of the loop compares very well to the code that uses a literal value for the loop limit. However, the code that uses a variable which contains the precomputed value for the loop limit is significantly slower than either of the others. I'm not surprised that accessing a variable should be slower that using a literal but why does code that looks like it should be using two multiply instructions on every iteration of the loop so comparable in performance to a literal?

Could it be that because literals are the only thing being multiplied, the Java compiler is optimizing out the multiplication and using a precomputed literal?

© Stack Overflow or respective owner

Related posts about android

Related posts about for-loop